home *** CD-ROM | disk | FTP | other *** search
/ The Very Best of Atari Inside / The Very Best of Atari Inside 1.iso / mint / mntlb20 / lib / lseek.c < prev    next >
C/C++ Source or Header  |  1991-04-15  |  2KB  |  78 lines

  1. #include <stddef.h>
  2. #include <stdio.h>
  3. #include <errno.h>
  4. #include <osbind.h>
  5. #include <memory.h>
  6. #include <string.h>
  7. #include "lib.h"
  8.  
  9. #ifdef __GNUC__
  10. #define alloca __builtin_alloca
  11. #endif
  12.  
  13. static long _real_lseek(h, where, how)
  14. int h;
  15. long where;
  16. int how;
  17. {
  18.     register long rv;
  19.     
  20.     rv = Fseek(where, h, how);
  21.     if(rv < 0)
  22.     errno = ((int) -rv);
  23.     return(rv);
  24. }
  25.  
  26. /*
  27.  * emulate berzerkly lseek too
  28.  */
  29. long lseek(handle, offset, mode)
  30. int handle;
  31. long offset;
  32. int mode;
  33. {
  34.     long current_pos;
  35.     long expected_pos;
  36.     long new_pos;
  37.     char *buf;
  38.     
  39.     if ( (mode == SEEK_END) || (offset <= 0) )
  40.     /* do it the usual way */
  41.     return(_real_lseek(handle, offset, mode));
  42.     
  43.     current_pos = _real_lseek(handle, 0L, SEEK_CUR); /* find out where we are */
  44.     if (mode == SEEK_SET)
  45.     expected_pos = offset;
  46.     else
  47.     expected_pos = offset + current_pos;
  48.     new_pos = _real_lseek(handle, offset, mode);
  49.     if (new_pos == expected_pos)
  50.     return(new_pos);
  51.     
  52.     /* otherwise extend file -- zero filling the hole */
  53.     if (new_pos < 0)        /* error? */
  54.     {
  55.     new_pos = _real_lseek(handle, 0L, SEEK_END);    /* go to eof */
  56.     }    
  57.     
  58.     buf  = (char *)alloca((size_t)256);
  59.     bzero(buf, (size_t)256);
  60.     while (expected_pos > new_pos)    
  61.     {
  62.     offset = expected_pos - new_pos;
  63.     if (offset > 256) 
  64.         offset = 256;
  65.     if((current_pos = _write(handle, buf, offset)) != offset)
  66.         return((current_pos > 0) ? (new_pos + current_pos) :
  67.            new_pos);    /* errno set by write */
  68.     new_pos += offset;
  69.     }
  70.     return(new_pos);  
  71. }
  72.  
  73. long tell(h)
  74. int h;
  75. {
  76.     return(_real_lseek(h, 0L, SEEK_CUR));
  77. }
  78.